package com.estore.network;

import com.estore.model.Product;
import com.estore.model.OrderRecord;
import com.estore.service.ShoppingCartService;
import com.estore.service.OrderService;

import java.io.*;
import java.net.Socket;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

public class EStoreClient {
    private final String serverHost;
    private final int serverPort;
    private final ShoppingCartService cartService;
    private final OrderService orderService;
    private final Scanner scanner;
    private boolean isRunning;

    public EStoreClient(String serverHost, int serverPort) {
        this.serverHost = serverHost;
        this.serverPort = serverPort;
        this.cartService = new ShoppingCartService();
        this.orderService = new OrderService();
        this.scanner = new Scanner(System.in);
        this.isRunning = true;
    }

    public EStoreClient() {
        this("localhost", 8888);
    }

    public void start() {
        displayWelcomeMessage();

        while (isRunning) {
            try {
                showMainMenu();
                int choice = getIntInput("请输入您的选择: ");
                handleMainMenuChoice(choice);
            } catch (Exception e) {
                System.out.println("发生错误: " + e.getMessage());
                System.out.println("请重新尝试。");
            }
        }

        cleanup();
    }

    private void displayWelcomeMessage() {
        System.out.println("====================================");
        System.out.println("        欢迎来到电子商城客户端");
        System.out.println("====================================");
    }

    private void showMainMenu() {
        System.out.println("\n=== 主菜单 ===");
        System.out.println("1. 浏览商品");
        System.out.println("2. 搜索商品");
        System.out.println("3. 购物车管理");
        System.out.println("4. 结算订单");
        System.out.println("5. 查看购物记录");
        System.out.println("6. 退出系统");
        System.out.println("===============");
    }

    private void handleMainMenuChoice(int choice) {
        switch (choice) {
            case 1 -> browseProducts();
            case 2 -> searchProducts();
            case 3 -> manageCart();
            case 4 -> checkout();
            case 5 -> viewOrderHistory();
            case 6 -> exitSystem();
            default -> System.out.println("无效的选项，请重新输入！");
        }
    }

    private void browseProducts() {
        System.out.println("\n--- 商品浏览 ---");
        System.out.println("1. 浏览所有商品");
        System.out.println("2. 浏览有库存商品");
        System.out.println("3. 按标签浏览");
        System.out.print("请选择浏览方式: ");

        int choice = scanner.nextInt();
        scanner.nextLine();

        List<Product> products;
        switch (choice) {
            case 1 -> products = sendRequest("GET_ALL_PRODUCTS");
            case 2 -> products = sendRequest("GET_AVAILABLE_PRODUCTS");
            case 3 -> {
                String tag = getStringInput("请输入标签: ");
                products = sendRequest("SEARCH_BY_TAG:" + tag);
            }
            default -> {
                System.out.println("无效选择！");
                return;
            }
        }

        displayProducts(products);

        if (!products.isEmpty()) {
            System.out.print("\n是否要添加商品到购物车？(y/n): ");
            if (scanner.nextLine().trim().equalsIgnoreCase("y")) {
                addToCartFromBrowse();
            }
        }
    }

    private void searchProducts() {
        String keyword = getStringInput("请输入搜索关键词: ");
        List<Product> results = sendRequest("SEARCH_BY_NAME:" + keyword);

        System.out.println("\n--- 搜索结果 ---");
        displayProducts(results);

        if (!results.isEmpty()) {
            System.out.print("\n是否要添加商品到购物车？(y/n): ");
            if (scanner.nextLine().trim().equalsIgnoreCase("y")) {
                addToCartFromBrowse();
            }
        }
    }

    @SuppressWarnings("unchecked")
    private <T> T sendRequest(String request) {
        Socket socket = null;
        try {
            socket = new Socket(serverHost, serverPort);
            ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());
            ObjectInputStream input = new ObjectInputStream(socket.getInputStream());

            // 发送请求
            output.writeObject(request);
            output.flush();

            // 接收响应
            Object response = input.readObject();

            if (response instanceof String && ((String) response).startsWith("ERROR:")) {
                throw new RuntimeException(((String) response).substring(6));
            }

            return (T) response;

        } catch (IOException e) {
            throw new RuntimeException("连接服务器失败: " + e.getMessage());
        } catch (ClassNotFoundException e) {
            throw new RuntimeException("解析服务器响应失败: " + e.getMessage());
        } finally {
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    System.err.println("关闭Socket连接时发生错误: " + e.getMessage());
                }
            }
        }
    }

    private Product findProductById(String productId) {
        return sendRequest("FIND_PRODUCT_BY_ID:" + productId);
    }

    private int checkStock(String productId) {
        return sendRequest("CHECK_STOCK:" + productId);
    }

    // 以下方法保持与原来 ConsoleShop 相同的实现，但使用网络调用替代直接服务调用
    private void manageCart() {
        while (true) {
            System.out.println("\n--- 购物车管理 ---");
            viewCart();

            if (cartService.getItemCount() == 0) {
                return;
            }

            System.out.println("\n1. 修改商品数量");
            System.out.println("2. 移除商品");
            System.out.println("3. 清空购物车");
            System.out.println("4. 返回主菜单");

            int choice = getIntInput("请选择操作: ");
            switch (choice) {
                case 1 -> updateCartItem();
                case 2 -> removeFromCart();
                case 3 -> clearCart();
                case 4 -> { return; }
                default -> System.out.println("无效选择！");
            }
        }
    }

    private void addToCartFromBrowse() {
        String productId = getStringInput("请输入商品ID: ");
        Product product = findProductById(productId);

        if (product != null && product.getStock() > 0) {
            int quantity = getIntInput("请输入数量: ");
            if (quantity > 0 && quantity <= product.getStock()) {
                cartService.addItem(productId, quantity);
                System.out.println("添加成功！");
            } else {
                System.out.println("数量无效！");
            }
        } else {
            System.out.println("商品不存在或库存不足！");
        }
    }

    private void updateCartItem() {
        String productId = getStringInput("请输入要修改的商品ID: ");

        Map<String, Integer> currentCart = cartService.getCart();
        if (!currentCart.containsKey(productId)) {
            System.out.println("购物车中不存在该商品！");
            return;
        }

        Product product = findProductById(productId);
        if (product == null) {
            System.out.println("商品不存在！");
            cartService.removeItem(productId);
            return;
        }

        int newQuantity = getIntInput("请输入新的数量 (输入0移除商品): ");
        if (newQuantity == 0) {
            cartService.removeItem(productId);
            System.out.println("已从购物车移除商品。");
        } else if (newQuantity > 0 && newQuantity <= product.getStock()) {
            cartService.updateItem(productId, newQuantity);
            System.out.println("数量更新成功！");
        } else {
            System.out.println("数量无效！");
        }
    }

    private void removeFromCart() {
        String productId = getStringInput("请输入要移除的商品ID: ");
        cartService.removeItem(productId);
        System.out.println("商品移除成功！");
    }

    private void clearCart() {
        System.out.print("确定要清空购物车吗？(y/n): ");
        if (scanner.nextLine().trim().equalsIgnoreCase("y")) {
            cartService.clearCart();
            System.out.println("购物车已清空！");
        }
    }

    private void checkout() {
        if (cartService.getItemCount() == 0) {
            System.out.println("购物车为空，无法结算！");
            return;
        }

        System.out.println("\n--- 订单结算 ---");
        viewCart();

        System.out.print("\n确认下单吗？(y/n): ");
        if (!scanner.nextLine().trim().equalsIgnoreCase("y")) {
            System.out.println("已取消下单。");
            return;
        }

        boolean success = processOrder();
        if (success) {
            Map<String, Integer> currentCart = cartService.getCart();
            double totalAmount = calculateCartTotal(currentCart);
            String orderId = orderService.generateOrderId();
            OrderRecord order = new OrderRecord(orderId, currentCart, totalAmount);
            orderService.addOrder(order);

            System.out.println("下单成功！订单号: " + orderId);
            System.out.println("感谢您的购买！");
            cartService.clearCart();
        } else {
            System.out.println("下单失败，请检查商品库存！");
        }
    }

    private boolean processOrder() {
        Map<String, Integer> currentCart = cartService.getCart();

        // 验证库存
        for (Map.Entry<String, Integer> entry : currentCart.entrySet()) {
            int stock = checkStock(entry.getKey());
            if (stock < entry.getValue()) {
                Product product = findProductById(entry.getKey());
                System.out.printf("商品 '%s' 库存不足！当前库存: %d, 需要: %d\n",
                        product != null ? product.getName() : entry.getKey(),
                        stock, entry.getValue());
                return false;
            }
        }

        // 注意：在C/S架构中，库存扣减应该在服务器端完成
        // 这里暂时保持本地扣减，后续可以扩展服务器接口
        for (Map.Entry<String, Integer> entry : currentCart.entrySet()) {
            // 这里应该调用服务器的库存扣减接口
            // 暂时跳过，因为服务器还没有实现库存扣减功能
        }

        return true;
    }

    private double calculateCartTotal(Map<String, Integer> cart) {
        double total = 0.0;
        for (Map.Entry<String, Integer> entry : cart.entrySet()) {
            Product product = findProductById(entry.getKey());
            if (product != null) {
                total += product.getPrice() * entry.getValue();
            }
        }
        return total;
    }

    private void viewCart() {
        Map<String, Integer> currentCart = cartService.getCart();

        if (currentCart.isEmpty()) {
            System.out.println("购物车是空的，快去逛逛吧！");
            return;
        }

        System.out.println("购物车内容:");
        System.out.println("================================================");

        double total = 0.0;
        int totalItems = 0;

        for (Map.Entry<String, Integer> entry : currentCart.entrySet()) {
            String productId = entry.getKey();
            Integer quantity = entry.getValue();
            Product product = findProductById(productId);

            if (product != null) {
                double subtotal = product.getPrice() * quantity;
                System.out.printf("ID: %-6s | 商品: %-20s | 单价: ¥%-8.2f | 数量: %-3d | 小计: ¥%-8.2f\n",
                        productId, product.getName(), product.getPrice(), quantity, subtotal);
                total += subtotal;
                totalItems += quantity;
            } else {
                System.out.printf("ID: %s - 商品信息不存在\n", productId);
            }
        }

        System.out.println("================================================");
        System.out.printf("商品种类: %d | 商品总数: %d | 订单总额: ¥%.2f\n",
                currentCart.size(), totalItems, total);
    }

    private void viewOrderHistory() {
        System.out.println("\n--- 购物记录 ---");
        List<OrderRecord> orders = orderService.getAllOrders();

        if (orders.isEmpty()) {
            System.out.println("暂无购物记录。");
            return;
        }

        System.out.println("==========================================================================================");
        System.out.printf("%-12s | %-20s | %-10s | %-6s | %s\n",
                "订单号", "下单时间", "总金额", "商品数", "商品详情");
        System.out.println("==========================================================================================");

        for (OrderRecord order : orders) {
            StringBuilder itemDetails = new StringBuilder();
            for (Map.Entry<String, Integer> entry : order.getItems().entrySet()) {
                Product product = findProductById(entry.getKey());
                String productName = product != null ? product.getName() : "未知商品";
                itemDetails.append(String.format("%s(%d) ", productName, entry.getValue()));
            }

            System.out.printf("%-12s | %-20s | ¥%-9.2f | %-6d | %s\n",
                    order.getOrderId(),
                    order.getOrderTime().toString().substring(0, 19),
                    order.getTotalAmount(),
                    order.getItems().size(),
                    itemDetails.toString());
        }
        System.out.println("==========================================================================================");
        System.out.printf("共 %d 条购物记录\n", orders.size());
    }

    private void exitSystem() {
        System.out.print("确定要退出系统吗？(y/n): ");
        if (scanner.nextLine().trim().equalsIgnoreCase("y")) {
            isRunning = false;
            System.out.println("感谢使用电子商城客户端，再见！");
        }
    }

    private void displayProducts(List<Product> products) {
        if (products.isEmpty()) {
            System.out.println("没有找到商品。");
            return;
        }

        System.out.println("==================================================================================");
        System.out.printf("%-6s | %-20s | %-10s | %-6s | %s\n",
                "ID", "商品名称", "价格", "库存", "标签");
        System.out.println("==================================================================================");

        for (Product product : products) {
            System.out.printf("%-6s | %-20s | ¥%-9.2f | %-6d | %s\n",
                    product.getId(),
                    truncateString(product.getName(), 20),
                    product.getPrice(),
                    product.getStock(),
                    String.join(", ", product.getTags()));
        }
        System.out.println("==================================================================================");
        System.out.printf("共 %d 个商品\n", products.size());
    }

    private String truncateString(String str, int maxLength) {
        if (str.length() <= maxLength) {
            return str;
        }
        return str.substring(0, maxLength - 3) + "...";
    }

    private int getIntInput(String prompt) {
        while (true) {
            try {
                System.out.print(prompt);
                int value = scanner.nextInt();
                scanner.nextLine(); // 消费换行符
                return value;
            } catch (Exception e) {
                System.out.println("请输入有效的数字！");
                scanner.nextLine(); // 清除无效输入
            }
        }
    }

    private String getStringInput(String prompt) {
        System.out.print(prompt);
        return scanner.nextLine().trim();
    }

    private void cleanup() {
        scanner.close();
    }

    public static void main(String[] args) {
        String host = "localhost";
        int port = 8888;

        if (args.length >= 1) {
            host = args[0];
        }
        if (args.length >= 2) {
            try {
                port = Integer.parseInt(args[1]);
            } catch (NumberFormatException e) {
                System.err.println("无效的端口号，使用默认端口: 8888");
            }
        }

        try {
            System.out.println("正在连接服务器 " + host + ":" + port + "...");
            EStoreClient client = new EStoreClient(host, port);
            client.start();
        } catch (Exception e) {
            System.err.println("客户端启动失败: " + e.getMessage());
            e.printStackTrace();
        }
    }
}